#include "Drv_AD7606.h"


// todo
#define RANGE (5)


/* IO info */
// todo

#define USE_BITBAND (0)
#if USE_BITBAND
  #include "bitband.h"

#else
  #define rst(x)    HAL_GPIO_WritePin(AD7606_RST_GPIO_Port,   AD7606_RST_Pin,   (x) ?GPIO_PIN_SET :GPIO_PIN_RESET)
  #define cva(x)    HAL_GPIO_WritePin(AD7606_CVA_GPIO_Port,   AD7606_CVA_Pin,   (x) ?GPIO_PIN_SET :GPIO_PIN_RESET)
  #define cvb(x)    HAL_GPIO_WritePin(AD7606_CVB_GPIO_Port,   AD7606_CVB_Pin,   (x) ?GPIO_PIN_SET :GPIO_PIN_RESET)
  #define busy()    HAL_GPIO_ReadPin (AD7606_BUSY_GPIO_Port,  AD7606_BUSY_Pin)
  #define scl(x)    HAL_GPIO_WritePin(AD7606_SCL_GPIO_Port,   AD7606_SCL_Pin,   (x) ?GPIO_PIN_SET :GPIO_PIN_RESET)
  #define miso()    HAL_GPIO_ReadPin (AD7606_MISO_GPIO_Port,  AD7606_MISO_Pin)
  #define cs(x)     HAL_GPIO_WritePin(AD7606_CS_GPIO_Port,    AD7606_CS_Pin,    (x) ?GPIO_PIN_SET :GPIO_PIN_RESET)
  #define stby(x)   HAL_GPIO_WritePin(AD7606_STBY_GPIO_Port,  AD7606_STBY_Pin,  (x) ?GPIO_PIN_SET :GPIO_PIN_RESET)
  #define ser(x)    HAL_GPIO_WritePin(AD7606_SER_GPIO_Port,   AD7606_SER_Pin,   (x) ?GPIO_PIN_SET :GPIO_PIN_RESET)
#endif


uint16_t readDualByte()
{
  uint32_t i;
  uint16_t dualByte;

  cs(0);
  for(i = 0; i < 16; i++)
  {
    scl(0);
    dualByte <<= 1;
    dualByte = dualByte | miso();
    scl(1);
  }
  cs(1);

  return dualByte;
}

void AD7606_Init()
{
  stby(1);
  ser(1);
  cs(1);
  scl(1);
	cva(1);
	cvb(1);

  rst(0);
  HAL_Delay(1);
  rst(1);
  HAL_Delay(1);
  rst(0);
  HAL_Delay(1);

  HAL_Delay(50);
}

void AD7606_readOnce(uint32_t en_channelA, int16_t* pBufA, uint32_t en_channelB, int16_t* pBufB)
{
  uint32_t i;

  if(en_channelA)
  {
    cva(0);
    cva(1);
    HAL_Delay(1);
  }
  if(en_channelB)
  {
    cvb(0);
    cvb(1);
    HAL_Delay(1);
  }
  while(busy());
  if(en_channelA)
  {
    for(i = 0; i < 4; ++i)
    {
      pBufA[i] = (int16_t)readDualByte();
    }
  }
  if(en_channelB)
  {
    for(i = 0; i < 4; ++i)
    {
      pBufB[i] = (int16_t)readDualByte();
    }
  }
}

void AD7606_conv(int16_t* pBufA, float* pDataA, int16_t* pBufB, float* pDataB)
{
  uint32_t i;

  if(pBufA)
  {
    for(i = 0; i < 4; ++i)
    {
      pDataA[i] = (float)pBufA[i] * RANGE / 32767;
    }
  }
  if(pBufB)
  {
    for(i = 0; i < 4; ++i)
    {
      pDataB[i] = (float)pBufB[i] * RANGE / 32767;
    }
  }
}
